package com.spark.sniffer.plugin.plugins.interceptor;

import java.lang.reflect.Method;

import com.spark.sniffer.constant.TracingDataConstant;
import com.spark.sniffer.logging.api.Logger;
import com.spark.sniffer.logging.api.LoggerFactory;
import com.spark.sniffer.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import com.spark.sniffer.plugin.interceptor.enhance.MethodInterceptResult;
import com.spark.sniffer.tracing.TracingContext;
import com.spark.sniffer.util.ReflectUtil;

/**
 * Spring ExceptionHandler注解插件，在此处理错误码（非http状态码）
 * 
 * @author Cobe
 *
 */
public class ExceptionHandlerInterceptor implements InstanceMethodsAroundInterceptor {
    private static final Logger log = LoggerFactory.getLogger(ExceptionHandlerInterceptor.class);

    @Override
    public void beforeMethod(Object instance, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
        MethodInterceptResult result) throws Throwable {}

    @Override
    public Object afterMethod(Object instance, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
        Object ret) throws Throwable {
        // ret: org.springframework.http.ResponseEntity
        Object body = ReflectUtil.getMethod(ret, "getBody").invoke();
        if (body == null) {
            return ret;
        }

        // 由于响应码不同应用定义不同，在此进行兼容
        // teaching_backend和微服务
        Object errcode = ReflectUtil.getMethod(body, "getCode").invoke();
        // app
        if (errcode == null) {
            errcode = ReflectUtil.getMethod(body, "getErrorCode").invoke();
        }

        if (errcode != null) {
            log.debug("errcode={}", errcode);
            TracingContext.getContext().putData(TracingDataConstant.ERRCODE, errcode);
        }

        return ret;
    }

    @Override
    public void handleMethodException(Object instance, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
        Throwable t) {}

}
